记一次Linux服务器CPU长期100%问题排查

您所在的位置:网站首页 linux pagecache 写日志 记一次Linux服务器CPU长期100%问题排查

记一次Linux服务器CPU长期100%问题排查

2023-04-25 07:02| 来源: 网络整理| 查看: 265

背景

几周前利用业余时间给朋友写了一个最近挺火的 midjourney 生成工具后端服务,采用的Java代码实现,昨天排查某个BUG登录上 Linux 服务器上查看程序日志,然后在 MobaXterm 自带终端的监控上看到服务器CPU一直长期处于100%的状态,对于2h4c的配置内存才差不多用一半多,QPS也很低,不至于CPU一直处于这么高的复杂,于是进行了一翻排查,本文针对解决情况做个记录。

排查步骤

登录服务器,查看CPU占用最高的所在进程,执行top -c,发现是 java 程序导致CPU飚高;

查看服务器日志,是否是因为请求量过大和机器性能不行,查看后不是这原因,于是进行下一步;

由于采用的是docker部署,所以宿主机查看 pid 无法定位具体问题,这里直接采用 arthas 定位到具体的问题;

docker stats 查看容器CPU占用最高的,然后使用docker exec -it {容器id} /bin/bash 进入容器 ;

由于 docker 安装都是最小化镜像,没有jdk环境,只有jre运行环境,无法执行类似于 jps 命令,所以先临时在docker容器中安装个jdk,然后启动 arthas 进行排查;

安装jdk和启动arthas命令步骤如下:

# 下载jdk wget https://mirrors.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz # 解压 tar -zxvf jdk-8u202-linux-x64.tar.gz # 下载 arthas wget https://arthas.aliyun.com/arthas-boot.jar # 启动 arthas ./jdk-8u202-linux-x64/bin/java -jar arthas-boot.jar

执行 thead -n 3 查看cpu最忙的3个线程,记录下pid;

继续执行 thead pid号,定位到具体的代码,我这里的日志如下:

[arthas@1]$ thread 5781 "http-nio-8080-exec-211" Id=5781 RUNNABLE at java.util.regex.Pattern$CharProperty.match(Pattern.java:3778) at java.util.regex.Pattern$Branch.match(Pattern.java:4606) at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660) at java.util.regex.Pattern$Loop.match(Pattern.java:4787) at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719) at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570) at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779) at java.util.regex.Pattern$Branch.match(Pattern.java:4606) at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660) at java.util.regex.Pattern$Loop.match(Pattern.java:4787) at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719) at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570) at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779) at java.util.regex.Pattern$Branch.match(Pattern.java:4606) at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660) at java.util.regex.Pattern$Loop.match(Pattern.java:4787) at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719) at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570) at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779)分析结果

根据排查的结果发现是因为正则匹配的时候循环浪费的资源,这个正则表达式代码只有在一个接口中做前置判断有用到,就快速定位到了是正则表达式的问题,查阅相关资料和询问ChatGPT后,大概确定问题就是因为正则表达式不规范导致循环进行失控模式,分析参考文章链接,感兴趣的可以点进去看下,最后采用修改正则表达式然后重新发布服务CPU使用恢复正常。

总结

在本次操作过程中,遇到了很多问题坑,很多参考文章都是基于linux的指令和借助jstack、jps命令来排查,然后也不是针对于容器内的java程序进行排查,并且容器对应的pid和宿主机对应的pid不是一回事,所以只有靠定位到具体容器,进入容器再进行排查,一般容器使用的基础镜像为了保证足够精简,所以常常命令也是太简单,所以需要临时安装一些环境,这里推荐给大家arthas这款工具确实能够大大减少针对java程序排查问题的复杂度。

最后还是要提醒多久爱,写正则表达式参考网上的很可能有问题,使用前还是多斟酌,以免出现类似的线上问题。

参考链接

Java诊断工具arthas官方文档 Java 进程 CPU 100% 问题排查 java 应用cpu飙升(超过100%)故障排查 Regex gone wild: java.util.regex.Pattern matcher goes into high CPU loop

function Catalogswith(){document.getElementById("catalog-col").classList.toggle("catalog");document.getElementById("catalog").classList.toggle("catalog")}



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3